﻿using Swifter.RW;
using System;
using System.Collections.Generic;

namespace Swifter.Api
{
    public sealed class ContextParameters
    {
        static ContextParameters()
        {
            ValueInterface<ContextParameters>.SetInterface(new Interface());
        }

        public ContextParameters()
        {
            CommandParameters = new Dictionary<string, ValueCopyer>();
        }

        /// <summary>
        /// 会话 Id。
        /// </summary>
        public string Token { get; set; }

        /// <summary>
        /// 客户端时间。
        /// </summary>
        public DateTimeOffset ClientTime { get; set; }

        /// <summary>
        /// 客户端指定返回值数据类型。
        /// </summary>
        public string ContentType { get; set; }

        /// <summary>
        /// 签名验证。
        /// </summary>
        public string Sign { get; set; }

        /// <summary>
        /// 客户端 IP 地址。
        /// </summary>
        public string IP { get; set; }

        /// <summary>
        /// 客户端请求服务器所使用的协议。
        /// </summary>
        public string Protocol { get; set; }

        /// <summary>
        /// 请求执行的命令名称。
        /// </summary>
        public string Command { get; set; }

        /// <summary>
        /// 命令参数。
        /// </summary>
        public Dictionary<string, ValueCopyer> CommandParameters { get; set; }

        /// <summary>
        /// 应用程序辅助变量。
        /// </summary>
        public object Tag { get; set; }

        sealed class Interface : IValueInterface<ContextParameters>
        {
            public ContextParameters ReadValue(IValueReader valueReader)
            {
                var writer = new Writer();

                valueReader.ReadObject(writer);

                return writer.Content;
            }

            public void WriteValue(IValueWriter valueWriter, ContextParameters value)
            {
                throw new DeveloperException($"'{nameof(ContextParameters)}' cannot be serialized.");
            }
        }

        sealed class Writer : IDataWriter<string>
        {
            public ContextParameters Content;

            public IValueWriter this[string key] => new WriteCopyer<string>(this, key);

            public IEnumerable<string> Keys => null;

            public int Count => 0;

            public void Initialize()
            {
                Content = new ContextParameters();
            }

            public void Initialize(int capacity)
            {
                Initialize();
            }

            public void OnWriteAll(IDataReader<string> dataReader)
            {
            }

            public void OnWriteValue(string key, IValueReader valueReader)
            {
                switch (key)
                {
                    case nameof(ClientTime):
                        Content.ClientTime = ValueInterface<DateTimeOffset>.ReadValue(valueReader);
                        break;
                    case nameof(Command):
                        Content.Command = ValueInterface<string>.ReadValue(valueReader);
                        break;
                    case nameof(ContentType):
                        Content.ContentType = ValueInterface<string>.ReadValue(valueReader);
                        break;
                    case nameof(Sign):
                        Content.Sign = ValueInterface<string>.ReadValue(valueReader);
                        break;
                    case nameof(Token):
                        Content.Token = ValueInterface<string>.ReadValue(valueReader);
                        break;
                    default:
                        Content.CommandParameters[key] = ValueInterface<ValueCopyer>.ReadValue(valueReader);
                        break;
                }
            }
        }
    }
}
